// This class is used to easily define cliques from a graph. A Clique is a subgraph of a given graph, in which all Points are
// connected to each other. So this class has a element member_Points that stores all Points that are part of this clique.
// Also it has different functions:
//		1. getMemberPoints(): This function returns a vector<cv::Point> with all members in it.
//		2. insertMember(cv::Point/vector<cv::Point)): This function takes one cv::Point or a vector of them and adds them to
//													  the member Points.
//		3. getNumberOfMembers(): This function returns the number of members in the clique.
//		4. getCliquePotential(vector<unsigned int> labels, vector<cv::CvBoost> boost_classifiers):
//				This function is used for the Voronoi Random Field Segmentation. It gets a list of AdaBoost classifiers
//				( from OpenCV ) and calculates the feature for this clique, depending on the given labels for each Point.
//				The labels show to which class each Point belongs and are describing the position of the AdaBoost classifier
//				in the given vector. It then calculates Phi(y_k, x) = exp(w_k^T * f_k(y_k, x)). Phi is the clique potential
//				needed for the conditional random field, w_k is the weight-vector, defined for each classifier and put together
//				for each point here and f_k is the feature vector, that calculates individual features for each point to label
//				them as a specific class. y_k are the member points of a clique and x is the hidden node of the conditional
//				random field, in this case the given gridmap.
//

#include <ipa_room_segmentation/contains.h>
#include <ipa_room_segmentation/voronoi_random_field_features.h>
#include <ipa_room_segmentation/raycasting.h>

#pragma once

class Clique
{
protected:
    // vector that stores the member points of the clique
    std::vector<cv::Point> member_points_;
    // vector that stores the simulated beams for each member (simulated using raycasting)
    std::vector<std::vector<double> > beams_for_members_;
public:
    // default constructor
    Clique();

    // constructor if one node is known
    Clique(cv::Point first_member);

    // constructor if more than one member point is known
    Clique(std::vector<cv::Point> members);

    // function that returns a vector with all member points stored in
    std::vector<cv::Point> getMemberPoints();

    // function that inserts a member if it isn't already a member
    void insertMember(cv::Point &new_member);

    // function that inserts multiple members, if they are not already members
    void insertMember(std::vector<cv::Point> &new_members);

    // function that checks if a given point is part of this clique
    bool containsMember(const cv::Point &point);

    // function that returns the number of members stored in this clique
    unsigned int getNumberOfMembers();

    // function that stores the given beams in the class parameter
    void setBeamsForMembers(const std::vector<std::vector<double> > beams);

    // function that returns the stored laser-beams for the member points
    std::vector<std::vector<double> > getBeams();
};
